package org.loong.crypto.extension.cms.jce;

import java.security.Key;
import java.security.PrivateKey;
import java.util.Objects;

import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.KeyTransRecipient;
import org.bouncycastle.operator.OperatorException;
import org.loong.crypto.extension.cms.EnvelopedDataHelper;
import org.loong.crypto.service.CryptoService;

public abstract class JceKeyTransRecipient implements KeyTransRecipient {

    protected EnvelopedDataHelper helper = new EnvelopedDataHelper();

    protected CryptoService cryptoService;

    private PrivateKey recipientKey;
    
    public JceKeyTransRecipient(CryptoService cryptoService, PrivateKey recipientKey) {
        this.cryptoService = cryptoService;
        this.recipientKey = recipientKey;
    }

    protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedEncryptionKey) throws CMSException {
        if (Objects.isNull(recipientKey)) {
            throw new CMSException("recipientKey cannot be null."); 
        }
        
        JceAsymmetricKeyUnwrapper unwrapper = new JceAsymmetricKeyUnwrapper(keyEncryptionAlgorithm, cryptoService, recipientKey);
        try {
            Key key = helper.getKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey));
            if (Objects.isNull(key)) {
                throw new CMSException("unwrapped key failed.");
            }
            return key;
        } catch (CMSException | OperatorException e) {
            throw new CMSException("exception unwrapping key: " + e.getMessage(), e);
        }
    }
}
